package com.crl.rcdp.gateway.util;

import org.apache.commons.collections4.CollectionUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;

import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @description:
 * @author: 孔垂云
 * @version: 1.0
 * @date: 2020/7/14 23:16
 */
public class IPUtil {
    public static String getIpAddress(ServerHttpRequest request) {
        HttpHeaders headers = request.getHeaders();
        String ip = headers.getFirst("x-forwarded-for");
        if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
            // 多次反向代理后会有多个ip值，第一个ip才是真实ip
            if (ip.indexOf(",") != -1) {
                ip = ip.split(",")[0];
            }
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = headers.getFirst("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = headers.getFirst("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = headers.getFirst("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = headers.getFirst("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = headers.getFirst("X-Real-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddress().getAddress().getHostAddress();
        }
        return ip;
    }


    /**
     * 判断ip是否在某个范围内
     *
     * @param ipSection
     * @param ip
     * @return
     */
    public static boolean ipIsValid(String ip, String ipSection) {
        return true;
     /*   if (ipSection == null) {
            return false;
        }
        if (ip == null) {
            return false;
        }
        ipSection = ipSection.trim();
        ip = ip.trim();
        final String REGX_IP = "((25[0-5]|2[0-4]//d|1//d{2}|[1-9]//d|//d)//.){3}(25[0-5]|2[0-4]//d|1//d{2}|[1-9]//d|//d)";
        final String REGX_IPB = REGX_IP + "//-" + REGX_IP;
        if (!ipSection.matches(REGX_IPB) || !ip.matches(REGX_IP)) {
            return false;
        }
        int idx = ipSection.indexOf('-');
        String[] sips = ipSection.substring(0, idx).split("//.");
        String[] sipe = ipSection.substring(idx + 1).split("//.");
        String[] sipt = ip.split("//.");
        long ips = 0L, ipe = 0L, ipt = 0L;
        for (int i = 0; i < 4; ++i) {
            ips = ips << 8 | Integer.parseInt(sips[i]);
            ipe = ipe << 8 | Integer.parseInt(sipe[i]);
            ipt = ipt << 8 | Integer.parseInt(sipt[i]);
        }
        if (ips > ipe) {
            long t = ips;
            ips = ipe;
            ipe = t;
        }
        return ips <= ipt && ipt <= ipe;*/
    }

    /**
     * 判断ip是否在白名单内
     *
     * @param ipList    ip列表
     * @param requestIp 请求ip
     * @return 是否在白名单内
     */
    public static boolean isValidIp(String requestIp, List<String> ipList) {
        if (ipList == null) {
            return false;
        }
        // 特殊IP设置，如果ip列表包含0.0.0.0，则不卡控ip
        if (ipList.contains(requestIp) || ipList.contains("0.0.0.0")) {
            return true;
        }
        ipList = ipList.stream().filter(ip -> ip.contains("~")).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(ipList)) {
            String regex = "([1-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}~(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])";
            for (String ip : ipList) {
                if (Pattern.matches(regex, ip)) {
                    String[] ipDetails = ip.split("\\.");
                    String[] ipEnds = ipDetails[3].split("~");
                    String[] ipStart = new String[4];
                    String[] ipEnd = new String[4];
                    for (int i = 0; i < 3; i++) {
                        ipStart[i] = ipDetails[i];
                        ipEnd[i] = ipDetails[i];
                    }
                    ipStart[3] = ipEnds[0];
                    ipEnd[3] = ipEnds[1];
                    String[] ipReq = requestIp.split("\\.");
                    long ips = 0L, ipe = 0L, ipr = 0L;
                    for (int i = 0; i < 4; ++i) {
                        ips = ips << 8 | Integer.parseInt(ipStart[i]);
                        ipe = ipe << 8 | Integer.parseInt(ipEnd[i]);
                        ipr = ipr << 8 | Integer.parseInt(ipReq[i]);
                    }
                    if (ips <= ipr && ipr <= ipe) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    public static void main(String[] args) {
        System.out.println(IPUtil.ipIsValid("192.168.1.4", "192.168.1.1-192.168.1.10"));
    }
}
